/**
 * Copyright 2020 jianggujin (www.jianggujin.com).
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jianggujin.dbfly.spring.annotation;

import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.Import;

/**
 * 使用JavaConfig时，使用此注释注册MyBatis映射器接口。
 *
 * <p>
 * 配置示例：
 * </p>
 * 
 * <pre class="code">
 * &#064;Configuration
 * &#064;JMapperScan("org.mybatis.spring.sample.mapper")
 * public class AppConfig {
 *
 *     &#064;Bean
 *     public DataSource dataSource() {
 *         return new EmbeddedDatabaseBuilder().addScript("schema.sql").build();
 *     }
 *
 *     &#064;Bean
 *     public DataSourceTransactionManager transactionManager() {
 *         return new DataSourceTransactionManager(dataSource());
 *     }
 *
 *     &#064;Bean
 *     public SqlSessionFactory sqlSessionFactory() throws Exception {
 *         SqlSessionFactoryBean sessionFactory = new JSqlSessionFactoryBean();
 *         sessionFactory.setDataSource(dataSource());
 *         return sessionFactory.getObject();
 *     }
 * }
 * </pre>
 *
 * @author jianggujin
 * @see JMapperScannerRegistrar
 * @see MapperFactoryBean
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(JMapperScannerRegistrar.class)
public @interface JMapperScan {

    /**
     * {@link #basePackages()}属性的别名
     */
    String[] value() default {};

    /**
     * 扫描MyBatis接口的基本包。仅会注册至少包含一个方法的接口，具体类将被忽略.
     */
    String[] basePackages() default {};

    /**
     * {@link #basePackages()}的类型安全替代方法，用于指定要扫描带注释组件的包。将扫描指定的每个类的包。
     * 考虑在每个包中创建一个特殊的no-op标记类或接口，该类或接口除了被此属性引用之外，没有其他用途。
     */
    Class<?>[] basePackageClasses() default {};

    /**
     * 用于命名Spring容器中检测到的组件的 {@link BeanNameGenerator}。
     */
    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

    /**
     * 此属性指定将搜索的注解。将注册基本包中也具有指定注解的所有接口。这可以与markerInterface结合使用
     */
    Class<? extends Annotation> annotationClass() default Annotation.class;

    /**
     * 此属性指定将搜索的父级。将注册基本包中也将指定接口类作为父类的所有接口。这可以与annotationClass结合使用
     */
    Class<?> markerInterface() default Class.class;

    /**
     * 指定在spring上下文中存在多个的情况下使用哪个{@code SqlSessionTemplate}。通常，只有在有多个数据源时才需要此功能。
     */
    String sqlSessionTemplateRef() default "";

    /**
     * 指定在spring上下文中存在多个时使用的{@code sqlsessionfactory}。通常只有当有多个数据源时才需要这样做。
     */
    String sqlSessionFactoryRef() default "";

    /**
     * 指定一个自定义的MapperFactoryBean以作为springbean返回mybatis代理
     *
     */
    @SuppressWarnings("rawtypes")
    Class<? extends MapperFactoryBean> factoryBean() default MapperFactoryBean.class;

}
